package com.nciae.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nciae.converter.OrderMaster2OrderDTOConverter;
import com.nciae.dto.CartDTO;
import com.nciae.dto.OrderDTO;
import com.nciae.enums.OrderStatusEnum;
import com.nciae.enums.PayStatusEnum;
import com.nciae.enums.ResultEnum;
import com.nciae.exception.SellException;
import com.nciae.po.OrderDetail;
import com.nciae.po.OrderMaster;
import com.nciae.dao.OrderMasterMapper;
import com.nciae.po.ProductInfo;
import com.nciae.service.IOrderDetailService;
import com.nciae.service.IOrderMasterService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nciae.service.IProductInfoService;
import org.apache.tomcat.util.bcel.classfile.SimpleElementValue;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单表 服务实现类
 * </p>
 *
 * @author YangChen
 * @since 2021-10-14
 */
@Service
public class OrderMasterServiceImpl extends ServiceImpl<OrderMasterMapper, OrderMaster> implements IOrderMasterService {


    @Autowired
    private IProductInfoService productInfoService;

    @Autowired
    private IOrderDetailService orderDetailService;

    @Override
    public OrderMaster findById(String id) {
        OrderMaster orderMaster = baseMapper.selectById(id);
        return orderMaster;
    }

    @Override
    public OrderMaster Insert(OrderMaster orderMaster) {
        baseMapper.insert(orderMaster);
        return baseMapper.selectById(orderMaster.getOrderId());
    }

    @Override
    @Transactional
    public OrderDTO create(OrderDTO orderDTO) throws SellException {
        // 查询商品数量，价格
        // 1.得到这个订单的商品详情
        List<OrderDetail> orderDetailList = orderDTO.getOrderDetailList();
        // 2.获得订单列表的迭代器
        Iterator<OrderDetail> iterator = orderDetailList.iterator();
        // 3.定义商品总价
        BigDecimal orderAmount = new BigDecimal(BigInteger.ZERO);
        while (iterator.hasNext()) {
            //3. 查询订单的商品详情
            OrderDetail orderDetail = iterator.next();
            ProductInfo productInfo = productInfoService.findOne(orderDetail.getProductId());
            if (productInfo == null) {
                throw new SellException(ResultEnum.PRODUCT_NOT_EXIST);
            }
            orderAmount= productInfo.getProductPrice().multiply(new BigDecimal(orderDetail.getProductQuantity())).add(orderAmount);
            // 5. todo：设置订单详情id，提醒订单id
            orderDetail.setOrderId(orderDTO.getOrderId());
            // 6.把商品信息复制到订单详情
            BeanUtils.copyProperties(productInfo,orderDetail);
            orderDetail.setCreateTime(orderDTO.getCreateTime());
            orderDetail.setUpdateTime(orderDTO.getUpdateTime());
            // 7.todo：新增一条订单信息
            orderDetailService.insert(orderDetail);
        }
        //4. 添加一条订单
        OrderMaster orderMaster = new OrderMaster();
        BeanUtils.copyProperties(orderDTO, orderMaster);
        orderMaster.setOrderAmount(orderAmount);
        orderMaster.setOrderStatus(OrderStatusEnum.NEW.getCode());
        orderMaster.setPayStatus(PayStatusEnum.WAIT.getCode());
        baseMapper.insert(orderMaster);

        List<CartDTO> cartDTOList = orderDetailList.stream().map(e -> new CartDTO(e.getProductId(), e.getProductQuantity())).collect(Collectors.toList());
        //5. 扣库存
        productInfoService.decreaseStock(cartDTOList);

        return orderDTO;
    }

    @Override
    public OrderDTO findOne(String orderId) throws SellException {
        OrderMaster orderMaster = baseMapper.selectById(orderId);
        if(orderMaster == null) {
            throw new SellException(ResultEnum.PRODUCT_NOT_EXIST);
        }
        List<OrderDetail> orderDetailList = orderDetailService.findByOrderId(orderId);
        if(CollectionUtils.isEmpty(orderDetailList)) {
            throw new SellException(ResultEnum.ORDER_DETAIL_EMPTY);
        }
        OrderDTO orderDTO = new OrderDTO();
        BeanUtils.copyProperties(orderMaster, orderDTO);
        orderDTO.setOrderDetailList(orderDetailList);
        return orderDTO;
    }

    @Override
    public IPage<OrderDTO> findByPage(Integer current, Integer size) {
        Page page = new Page();page.setCurrent(current);page.setSize(size);
        IPage OrderDTOPages = baseMapper.selectPage(page, null);
        List<OrderMaster> orderMasterList = OrderDTOPages.getRecords();
        List<OrderDTO> orderDTOList = OrderMaster2OrderDTOConverter.convert(orderMasterList);
        OrderDTOPages.setRecords(orderDTOList);
        return OrderDTOPages;
    }

    @Override
    @Transactional
    public OrderDTO cancel(OrderDTO orderDTO) throws SellException {

        // 更改商品状态
        OrderMaster orderMaster = new OrderMaster();
        if (!orderDTO.getOrderStatus().equals(OrderStatusEnum.NEW.getCode())) {
            throw new SellException(ResultEnum.ORDER_STATUS_ERROR);
        }
        orderDTO.setOrderStatus(OrderStatusEnum.CANCEL.getCode());
        BeanUtils.copyProperties(orderDTO, orderMaster);
        baseMapper.updateById(orderMaster);

        // 更新商品库存
        if (CollectionUtils.isEmpty(orderDTO.getOrderDetailList())) {
            throw new SellException(ResultEnum.ORDER_DETAIL_EMPTY);
        }
        List<OrderDetail> orderDetailList = orderDTO.getOrderDetailList();

        List<CartDTO> cartDTOList = orderDetailList.stream().map(e -> {
            return new CartDTO(e.getProductId(), e.getProductQuantity());
        }).collect(Collectors.toList());
        productInfoService.increaseStock(cartDTOList);

        // todo:如果支付必须要退款
        return orderDTO;
    }

    @Override
    @Transactional
    public OrderDTO finish(OrderDTO orderDTO) throws SellException {
        // 更改商品状态
        OrderMaster orderMaster = new OrderMaster();
        if (!orderDTO.getOrderStatus().equals(OrderStatusEnum.NEW.getCode())) {
            throw new SellException(ResultEnum.ORDER_STATUS_ERROR);
        }
        orderDTO.setOrderStatus(OrderStatusEnum.FINISHED.getCode());
        BeanUtils.copyProperties(orderDTO, orderMaster);
        baseMapper.updateById(orderMaster);
        return orderDTO;
    }

}
